# -*- coding: utf-8 -*-
"""
日志工具模块

本模块提供了基于loguru的日志配置和管理功能。
loguru是一个现代化的Python日志库，提供了简洁的API和强大的功能。

主要特性：
1. 彩色控制台输出：在开发环境中提供易读的彩色日志
2. 文件日志记录：自动轮转和保留策略的文件日志
3. 结构化格式：统一的日志格式，便于解析和分析
4. 性能优化：高效的日志处理，不影响应用性能
5. 异常捕获：自动记录异常堆栈信息

使用场景：
- 应用启动时的日志初始化
- 开发调试时的信息输出
- 生产环境的错误追踪
- 性能监控和分析
- 审计和合规要求

Examples:
    >>> from src.utils.logger import setup_logger
    >>> logger = setup_logger("my_app")
    >>> logger.info("应用启动成功")
    >>> logger.error("发生错误: {error}", error="连接失败")
"""
import os
import sys
from pathlib import Path
from typing import Optional
from loguru import logger
from config.settings import settings


def setup_logger(name: str = "llm_backend", 
                 console_level: Optional[str] = None,
                 file_level: Optional[str] = None,
                 log_dir: Optional[str] = None) -> logger:
    """
    设置和配置loguru日志器
    
    这个函数配置了一个完整的日志系统，包括控制台输出和文件记录。
    支持彩色输出、自动轮转、日志保留等高级功能。
    
    配置特性：
    1. 双重输出：同时输出到控制台和文件
    2. 级别控制：可以为控制台和文件设置不同的日志级别
    3. 格式化：美观的彩色控制台格式和结构化文件格式
    4. 自动轮转：文件大小达到限制时自动创建新文件
    5. 保留策略：自动删除过期的日志文件
    6. 编码支持：使用UTF-8编码支持中文日志
    
    Args:
        name (str): 日志器名称，用于标识不同的应用或模块
                   默认为"llm_backend"
        console_level (str, optional): 控制台日志级别，如"DEBUG", "INFO", "WARNING", "ERROR"
                                     如果未指定，使用配置文件中的设置
        file_level (str, optional): 文件日志级别，如果未指定，默认为"INFO"
        log_dir (str, optional): 日志文件目录，如果未指定，使用"logs"目录
    
    Returns:
        logger: 配置好的loguru日志器实例
    
    Raises:
        OSError: 当无法创建日志目录时
        PermissionError: 当没有写入权限时
    
    Examples:
        >>> # 基本使用
        >>> logger = setup_logger()
        >>> logger.info("应用启动")
        
        >>> # 自定义配置
        >>> logger = setup_logger(
        ...     name="my_module",
        ...     console_level="DEBUG",
        ...     file_level="WARNING",
        ...     log_dir="/var/log/myapp"
        ... )
        
        >>> # 记录不同级别的日志
        >>> logger.debug("调试信息: 变量值为 {value}", value=42)
        >>> logger.info("信息: 处理完成")
        >>> logger.warning("警告: 配置项缺失")
        >>> logger.error("错误: 连接失败")
        
        >>> # 异常记录
        >>> try:
        ...     1 / 0
        ... except Exception as e:
        ...     logger.exception("发生异常")
    
    Note:
        - 日志文件会自动轮转，当文件大小超过10MB时创建新文件
        - 日志文件保留30天，超过时间的文件会被自动删除
        - 控制台输出支持彩色显示，便于开发调试
        - 文件输出使用纯文本格式，便于日志分析工具处理
    """
    try:
        # 移除所有默认处理器，确保干净的配置环境
        logger.remove()
        
        # 确定日志级别
        console_level = console_level or settings.LOG_LEVEL
        file_level = file_level or "INFO"
        
        # 确定日志目录
        log_directory = log_dir or "logs"
        
        # 创建日志目录（如果不存在）
        log_path = Path(log_directory)
        log_path.mkdir(parents=True, exist_ok=True)
        
        # 验证目录权限
        if not os.access(log_path, os.W_OK):
            raise PermissionError(f"没有写入日志目录的权限: {log_path}")
        
        # 配置控制台处理器
        # 使用彩色格式，便于开发时查看
        console_format = (
            "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
            "<level>{level: <8}</level> | "
            "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
            "<level>{message}</level>"
        )
        
        logger.add(
            sink=sys.stdout,
            level=console_level,
            format=console_format,
            colorize=True,
            backtrace=True,  # 显示异常回溯
            diagnose=True    # 显示变量值
        )
        
        # 配置文件处理器
        # 使用纯文本格式，便于日志分析
        file_format = (
            "{time:YYYY-MM-DD HH:mm:ss} | "
            "{level: <8} | "
            "{name}:{function}:{line} - "
            "{message}"
        )
        
        # 构建日志文件路径
        log_file_path = log_path / settings.LOG_FILE.split('/')[-1]
        
        logger.add(
            sink=str(log_file_path),
            level=file_level,
            format=file_format,
            rotation="10 MB",      # 文件大小轮转
            retention="30 days",   # 保留时间
            compression="zip",     # 压缩旧文件
            encoding="utf-8",      # 支持中文
            backtrace=True,        # 记录异常回溯
            diagnose=True          # 记录变量值
        )
        
        # 记录日志系统初始化信息
        logger.info(f"日志系统初始化完成 - 名称: {name}")
        logger.info(f"控制台日志级别: {console_level}")
        logger.info(f"文件日志级别: {file_level}")
        logger.info(f"日志文件路径: {log_file_path}")
        
        return logger
        
    except Exception as e:
        # 如果日志配置失败，使用基本的控制台输出
        print(f"日志系统初始化失败: {e}")
        print("使用基本控制台日志")
        
        logger.remove()
        logger.add(sys.stdout, level="INFO")
        return logger


def get_logger(name: str = "llm_backend") -> logger:
    """
    获取已配置的日志器实例
    
    这是一个便捷函数，用于在应用的其他部分获取日志器。
    如果日志器尚未配置，会自动调用setup_logger进行初始化。
    
    Args:
        name (str): 日志器名称
    
    Returns:
        logger: 日志器实例
    
    Examples:
        >>> from src.utils.logger import get_logger
        >>> logger = get_logger("my_module")
        >>> logger.info("模块启动")
    """
    # 检查是否已有处理器，如果没有则初始化
    if not logger._core.handlers:
        setup_logger(name)
    
    return logger


def log_function_call(func):
    """
    装饰器：自动记录函数调用
    
    这个装饰器可以自动记录函数的调用和返回，便于调试和监控。
    
    Args:
        func: 要装饰的函数
    
    Returns:
        装饰后的函数
    
    Examples:
        >>> @log_function_call
        ... def my_function(x, y):
        ...     return x + y
        >>> 
        >>> result = my_function(1, 2)
        # 自动记录: 调用 my_function(1, 2)
        # 自动记录: my_function 返回 3
    """
    def wrapper(*args, **kwargs):
        func_name = func.__name__
        logger.debug(f"调用函数 {func_name}，参数: args={args}, kwargs={kwargs}")
        
        try:
            result = func(*args, **kwargs)
            logger.debug(f"函数 {func_name} 执行成功，返回: {result}")
            return result
        except Exception as e:
            logger.error(f"函数 {func_name} 执行失败: {e}")
            raise
    
    return wrapper


def configure_third_party_loggers():
    """
    配置第三方库的日志级别
    
    某些第三方库可能产生过多的日志输出，这个函数可以调整它们的日志级别。
    
    Examples:
        >>> configure_third_party_loggers()
        # 减少第三方库的日志噪音
    """
    import logging
    
    # 常见的第三方库日志配置
    third_party_loggers = {
        'urllib3': 'WARNING',
        'requests': 'WARNING', 
        'httpx': 'WARNING',
        'langchain': 'INFO',
        'transformers': 'WARNING',
        'torch': 'WARNING',
        'tensorflow': 'ERROR'
    }
    
    for logger_name, level in third_party_loggers.items():
        logging.getLogger(logger_name).setLevel(getattr(logging, level))
    
    logger.debug("第三方库日志级别配置完成")


# 模块级别的日志器实例
# 可以直接导入使用: from src.utils.logger import module_logger
module_logger = get_logger("utils.logger")